package com.mojo.concurrent.concurrent_02_lock;

/**
 * synchronized,wait示例
 * await超时，实现线程顺序执行
 *
 * @author <a href="mailto:sjj@jianzhimao.com">mojo</a>
 * copyright (C), 2013-2022, 广州九尾信息科技有限公司
 * @date 2022/3/17 15:09
 */
public class SynchronizationWait2 {
    public static void main(String[] args) {
        Thread t1 = new Thread(new Thread1(), "线程1");
        Thread t2 = new Thread(new Thread2(), "线程2");
        Thread t3 = new Thread(new Thread3(), "线程3");
        t1.start();
        t2.start();
        t3.start();
    }
}

class CommonService {
    final static Object obj = new Object();
    static Integer thread = 1;

    public void doWork() {
        //1.执行公共资源操作
        System.out.println(Thread.currentThread().getName());
        try {
            Thread.sleep(1000L);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

class Thread1 implements Runnable {
    CommonService service = new CommonService();

    @Override
    public void run() {
        for (; ; ) {
            synchronized (CommonService.obj) {
                if (CommonService.thread != 1) {
                    try {
                        CommonService.obj.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                System.out.println(">>>>>>>>>>111");
                service.doWork();
                CommonService.thread = 2;
                CommonService.obj.notifyAll();
            }
        }
    }
}

class Thread2 implements Runnable {
    CommonService service = new CommonService();

    @Override
    public void run() {
        for (; ; ) {
            synchronized (CommonService.obj) {
                if (CommonService.thread != 2) {
                    try {
                        CommonService.obj.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                System.out.println(">>>>>>>>>>222");
                service.doWork();
                CommonService.thread = 3;
                CommonService.obj.notifyAll();
            }
        }
    }
}

class Thread3 implements Runnable {
    CommonService service = new CommonService();

    @Override
    public void run() {
        for (; ; ) {
            synchronized (CommonService.obj) {
                if (CommonService.thread != 3) {
                    try {
                        CommonService.obj.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                System.out.println(">>>>>>>>>>333");
                service.doWork();
                CommonService.thread = 1;
                CommonService.obj.notifyAll();
            }
        }

    }
}
